#include <QtCore>
#include <QCoreApplication>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>

#include "gtype.h"
#include "klog.h"
#include "KjDevice.h"
#include "Hy103Client.h"
#include "DeviceProtocol.h"
#include "Debug.h"
#include "PanelLed.h"
#include "kWatchDog.h"
#include "EthProtocolBattery.h"

ParamEthernet gEthernetParm[]={
		{"","192.168.0.83","255.255.255.0"},
		{"","192.168.1.83","255.255.255.0"}
};

QString gswitchAddr="192.168.1.2";
QString gswitchType="Moxa";

QString gCan0Bitrate;
QString gCan1Bitrate;

ParamSerial gSerialParm[]={
		{"2400","8","1",0},
		{"2400","8","1",0},
		{"2400","8","1",0},
		{"2400","8","1",0}
};

qint8 gMprDevice=1;

QList<ParamDevice*> gDeviceListParam;

QMap<quint32,ParamHy103Cpu*> gHy103Cpu;

QList<ParamDeviceProtocol*> gDeviceProtocolParam;

QString gActiveSector;
QString gWorkDir;

klog* glog;

PanelLed* gled;

kWatchDog* gwatchDog;

QString gversion="0.9.5.101612RC";

/*
 * make a true rand
 */
static unsigned int new_rand ()
{
	int fd;
	unsigned int n = 0;

	fd = open ("/dev/urandom", O_RDONLY);
	if (fd > 0){
		read (fd, &n, sizeof (n));
	}
	close (fd);

	return n;
}
/*
 * change rand number to char
 */
static unsigned char randomchar(void)
{
	unsigned char a;

	a =(unsigned char)new_rand();
	if (a < 'A')
		a = a % 10 + 48;
	else if (a < 'F')
		a = a % 6 + 65;
	else if (a < 'a' || a > 'f')
		a = a % 6 + 97;

	return a;
}
/*
 * product one mac addr
 */
static QString product_one_mac(void)
{
	char mac[18]={'0','0',};
	int i;
	/*set mac addr */
	for (i=3; i<17; i++){
		usleep(10);
		mac[i] = randomchar();
	}

	mac[2]=mac[5]=mac[8]=mac[11]=mac[14]=':';
	mac[17]='\0';

	QString str(mac);
	return str;
}

void ParamUseDefault()
{
	gEthernetParm[0].mac=product_one_mac().toUpper();
	gEthernetParm[0].ip="192.168.0.83";
	gEthernetParm[0].netmask="255.255.255.0";

	gEthernetParm[1].mac=product_one_mac().toUpper();
	gEthernetParm[1].ip="192.168.1.83";
	gEthernetParm[1].netmask="255.255.255.0";

	gswitchAddr="192.168.1.2";
	gswitchType="Moxa";

	gCan0Bitrate="25K";
	gCan1Bitrate="25K";

	gSerialParm[0].bitrate="2400";
	gSerialParm[0].charbits="8";
	gSerialParm[0].stopbits="1";
	gSerialParm[0].parity=0;

	gSerialParm[1].bitrate="2400";
	gSerialParm[1].charbits="8";
	gSerialParm[1].stopbits="1";
	gSerialParm[1].parity=0;

	gSerialParm[2].bitrate="2400";
	gSerialParm[2].charbits="8";
	gSerialParm[2].stopbits="1";
	gSerialParm[2].parity=0;

	gSerialParm[3].bitrate="115200";
	gSerialParm[3].charbits="8";
	gSerialParm[3].stopbits="1";
	gSerialParm[3].parity=0;

	gMprDevice=1;

	qDeleteAll(gDeviceListParam);
	gDeviceListParam.clear();

	qDeleteAll(gHy103Cpu);
	gHy103Cpu.clear();

	ParamHy103Cpu* hy103Cpu;

	for(int i=1;i<32;i++)
	{
		hy103Cpu=new ParamHy103Cpu;
		hy103Cpu->devId=i;
		gHy103Cpu.insert(i,hy103Cpu);
	}

	qDeleteAll(gDeviceProtocolParam);
	gDeviceProtocolParam.clear();

	ParamDeviceProtocol* deviceProtocol;

	deviceProtocol=new ParamDeviceProtocol;
	deviceProtocol->id=1;
	deviceProtocol->type="can-mpr";
	deviceProtocol->devNode="can0";
	gDeviceProtocolParam.append(deviceProtocol);

	deviceProtocol=new ParamDeviceProtocol;
	deviceProtocol->id=2;
	deviceProtocol->type="can-mpr";
	deviceProtocol->devNode="can1";
	gDeviceProtocolParam.append(deviceProtocol);

	deviceProtocol=new ParamDeviceProtocol;
	deviceProtocol->id=3;
	deviceProtocol->type="rs485-test";
	deviceProtocol->devNode="/dev/ttyS1";
	gDeviceProtocolParam.append(deviceProtocol);

	deviceProtocol=new ParamDeviceProtocol;
	deviceProtocol->id=4;
	deviceProtocol->type="rs485-test";
	deviceProtocol->devNode="/dev/ttyS2";
	gDeviceProtocolParam.append(deviceProtocol);

	deviceProtocol=new ParamDeviceProtocol;
	deviceProtocol->id=5;
	deviceProtocol->type="rs485-test";
	deviceProtocol->devNode="/dev/ttyS3";
	gDeviceProtocolParam.append(deviceProtocol);

	deviceProtocol=new ParamDeviceProtocol;
	deviceProtocol->id=6;
	deviceProtocol->type="BatteryStatus";
	deviceProtocol->devNode="/dev/ttyS4";
	gDeviceProtocolParam.append(deviceProtocol);

}

bool loadParam()
{
	QDir paramDir(gWorkDir);

	if(!paramDir.exists())
	{
		glog->writeLog(llError,"loadParam","Working directory no found");
		return false;
	}

	if(!paramDir.cd(gActiveSector))
	{
		glog->writeLog(llError,"loadParam","Parameter sector not found");
		return false;
	}

	QFile paramFile;
	QDataStream ds;

	// Hardware parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/hardware.ky");
	if(!paramFile.open(QIODevice::ReadOnly))
	{
		glog->writeLog(llError,"loadParam","Open hardware parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);
	ds>>gEthernetParm[0].mac>>gEthernetParm[0].ip>>gEthernetParm[0].netmask
	  >>gEthernetParm[1].mac>>gEthernetParm[1].ip>>gEthernetParm[1].netmask
	  >>gswitchAddr>>gswitchType
	  >>gCan0Bitrate>>gCan1Bitrate
	  >>gSerialParm[0].bitrate>>gSerialParm[0].charbits>>gSerialParm[0].stopbits>>gSerialParm[0].parity
	  >>gSerialParm[1].bitrate>>gSerialParm[1].charbits>>gSerialParm[1].stopbits>>gSerialParm[1].parity
	  >>gSerialParm[2].bitrate>>gSerialParm[2].charbits>>gSerialParm[2].stopbits>>gSerialParm[2].parity
	  >>gSerialParm[3].bitrate>>gSerialParm[3].charbits>>gSerialParm[3].stopbits>>gSerialParm[3].parity;

	paramFile.close();

	// Device parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/device.ky");
	if(!paramFile.open(QIODevice::ReadOnly))
	{
		glog->writeLog(llError,"loadParam","Open device parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	ds>>gMprDevice;

	qint32 deviceCount;
	ParamDevice* device;

	qDeleteAll(gDeviceListParam);
	gDeviceListParam.clear();

	ds>>deviceCount;
	for(int i=0;i<deviceCount;i++)
	{
		device=new ParamDevice;
		ds>>device->id>>device->type
			>>device->lstAi
			>>device->lstDi
			>>device->lstPi
			>>device->lstDo
			>>device->lstAo
			>>device->lstAction
			>>device->lstAlarm;

		gDeviceListParam.append(device);
	}

	paramFile.close();

	// Protocol 103 parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/hy103.ky");
	if(!paramFile.open(QIODevice::ReadOnly))
	{
		glog->writeLog(llError,"loadParam","Open protocol 103 parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	qDeleteAll(gHy103Cpu);
	gHy103Cpu.clear();

	qint32 cpuCount;
	ParamHy103Cpu* hy103Cpu;
	quint32 cpuId;

	if(gMprDevice)
	{
		for(int i=1;i<32;i++)
		{
			hy103Cpu=new ParamHy103Cpu;
			hy103Cpu->devId=i;
			hy103Cpu->needAnalysis=0;
			gHy103Cpu.insert(i,hy103Cpu);
		}
	}

	ds>>cpuCount;

	for(int i=0;i<cpuCount;i++)
	{
		hy103Cpu=new ParamHy103Cpu;

		ds>>cpuId;

		ds>>hy103Cpu->devId>>hy103Cpu->needAnalysis
			>>hy103Cpu->lstAi
			>>hy103Cpu->lstDi
			>>hy103Cpu->lstPi
			>>hy103Cpu->lstDo
			>>hy103Cpu->lstAo
			>>hy103Cpu->lstAction
			>>hy103Cpu->lstAlarm;

		gHy103Cpu.insert(cpuId,hy103Cpu);
	}

	paramFile.close();

	// Device protocol parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/DeviceProtocol.ky");
	if(!paramFile.open(QIODevice::ReadOnly))
	{
		glog->writeLog(llError,"loadParam","Open device protocol parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	qint32 protocolCount;
	ParamDeviceProtocol* protocol;

	qDeleteAll(gDeviceProtocolParam);
	gDeviceProtocolParam.clear();

	if(gMprDevice)
	{
		protocol=new ParamDeviceProtocol;
		protocol->id=1;
		protocol->type="can-mpr";
		protocol->devNode="can0";
		gDeviceProtocolParam.append(protocol);

		protocol=new ParamDeviceProtocol;
		protocol->id=2;
		protocol->type="can-mpr";
		protocol->devNode="can1";
		gDeviceProtocolParam.append(protocol);
	}

	ds>>protocolCount;
	for(int i=0;i<protocolCount;i++)
	{
		protocol=new ParamDeviceProtocol;
		ds>>protocol->id>>protocol->type>>protocol->devNode;
		gDeviceProtocolParam.append(protocol);
	}

	paramFile.close();

	return true;
}

bool loadParam(const QString& workDir,const QString & activeSector)
{
	gWorkDir=workDir;
	gActiveSector=activeSector;

	return loadParam();
}

bool saveParam()
{
	QDir paramDir(gWorkDir);

	if(!paramDir.exists())
	{
		paramDir.mkpath(gWorkDir);
		paramDir.mkdir(gActiveSector);
	}

	if(!paramDir.cd(gActiveSector))
	{
		paramDir.mkdir(gActiveSector);
		paramDir.cd(gActiveSector);
	}

	QFile paramFile;
	QDataStream ds;

	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/hardware.ky");
	if(!paramFile.open(QIODevice::WriteOnly))
	{
		glog->writeLog(llError,"saveParam","Open hardware parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);
	ds<<gEthernetParm[0].mac<<gEthernetParm[0].ip<<gEthernetParm[0].netmask
	  <<gEthernetParm[1].mac<<gEthernetParm[1].ip<<gEthernetParm[1].netmask
	  <<gswitchAddr<<gswitchType
	  <<gCan0Bitrate<<gCan1Bitrate
	  <<gSerialParm[0].bitrate<<gSerialParm[0].charbits<<gSerialParm[0].stopbits<<gSerialParm[0].parity
	  <<gSerialParm[1].bitrate<<gSerialParm[1].charbits<<gSerialParm[1].stopbits<<gSerialParm[1].parity
	  <<gSerialParm[2].bitrate<<gSerialParm[2].charbits<<gSerialParm[2].stopbits<<gSerialParm[2].parity
	  <<gSerialParm[3].bitrate<<gSerialParm[3].charbits<<gSerialParm[3].stopbits<<gSerialParm[3].parity;

	paramFile.close();

	paramFile.setFileName(gWorkDir+"/switch.ky");
	if(!paramFile.open(QIODevice::WriteOnly))
	{
		glog->writeLog(llError,"savedParam","Open switch parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	ds<<gswitchAddr<<gswitchType;

	paramFile.close();

	// Protocol 103 parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/hy103.ky");
	if(!paramFile.open(QIODevice::WriteOnly))
	{
		glog->writeLog(llError,"savedParam","Open protocol 103 parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	qint32 cpuCount;
	ParamHy103Cpu* hy103Cpu;

	cpuCount=gHy103Cpu.size();

	QMap<quint32,ParamHy103Cpu*>::const_iterator iHy103Cpu=gHy103Cpu.constBegin();

	while(iHy103Cpu!=gHy103Cpu.constEnd())
	{
		if(gMprDevice&&iHy103Cpu.key()<32)
		{
			iHy103Cpu++;
			continue;
		}
		ds<<iHy103Cpu.key();
		hy103Cpu=iHy103Cpu.value();
		ds<<hy103Cpu->devId<<hy103Cpu->needAnalysis
			<<hy103Cpu->lstAi
			<<hy103Cpu->lstDi
			<<hy103Cpu->lstPi
			<<hy103Cpu->lstDo
			<<hy103Cpu->lstAo
			<<hy103Cpu->lstAction
			<<hy103Cpu->lstAlarm;
		iHy103Cpu++;
	}

	paramFile.close();

	// Device parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/device.ky");
	if(!paramFile.open(QIODevice::WriteOnly))
	{
		glog->writeLog(llError,"saveParam","Open device parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	ds<<gMprDevice;

	qint32 deviceCount=gDeviceListParam.size();
	ParamDevice* device;

	ds<<deviceCount;
	for(int i=0;i<deviceCount;i++)
	{
		device=gDeviceListParam[i];
		ds<<device->id<<device->type
			<<device->lstAi
			<<device->lstDi
			<<device->lstPi
			<<device->lstDo
			<<device->lstAo
			<<device->lstAction
			<<device->lstAlarm;
	}

	paramFile.close();

	// Device protocol parameter
	paramFile.setFileName(gWorkDir+"/"+gActiveSector+"/DeviceProtocol.ky");
	if(!paramFile.open(QIODevice::WriteOnly))
	{
		glog->writeLog(llError,"saveParam","Open device protocol parameter file failed");
		return false;
	}

	ds.setDevice(&paramFile);

	qint32 protocolCount=gDeviceProtocolParam.size();
	ParamDeviceProtocol* protocol;

	if(gMprDevice)
		ds<<protocolCount-2;
	else
		ds<<protocolCount;

	for(int i=0;i<protocolCount;i++)
	{
		protocol=gDeviceProtocolParam[i];
		if(protocol->id>2)
			ds<<protocol->id<<protocol->type<<protocol->devNode;
	}

	paramFile.close();

	return true;
}

QStringList sectorList()
{
	QStringList lstSector;
	QDir paramDir(gWorkDir);

	if(!paramDir.exists())
	{
		return lstSector;
	}

	lstSector=paramDir.entryList(QDir::Dirs|QDir::NoDotAndDotDot);

	return lstSector;
}

quint32 getCanBitrate(const QString& bitrate)
{
	if(bitrate=="12.5K")
		return 12500;
	else if(bitrate=="25K")
		return 25000;
	else if(bitrate=="50K")
		return 50000;
	else if(bitrate=="100K")
		return 100000;
	else if(bitrate=="31.25K")
		return 31250;
	else if(bitrate=="62.5K")
		return 62500;
	else if(bitrate=="125K")
		return 125000;
	else if(bitrate=="250K")
		return 250000;
	else if(bitrate=="1M")
		return 1000000;
	else
		return 0;
}

bool initHardware(bool nfs)
{
	QString strCmd;
	// Ethernet
	if(!nfs)
	{
		strCmd=QString("ifconfig eth0 down");
		::system(strCmd.toAscii().data());

		strCmd=QString("ifconfig eth0 hw ether %1").arg(gEthernetParm[0].mac);
		if(::system(strCmd.toAscii().data())==-1)
		{
			glog->writeLog(llError,"initHardware","Set eth0 mac address failed");
			return false;
		}

		strCmd=QString("ifconfig eth0 %1 netmask %2").arg(gEthernetParm[0].ip)
				.arg(gEthernetParm[0].netmask);
		if(::system(strCmd.toAscii().data())==-1)
		{
			glog->writeLog(llError,"initHardWare","Set eth0 ip address failed");
			return false;
		}
	}

	strCmd=QString("ifconfig eth1 down");
	::system(strCmd.toAscii().data());

	strCmd=QString("ifconfig eth1 hw ether %1").arg(gEthernetParm[1].mac);
	if(::system(strCmd.toAscii().data())==-1)
	{
		glog->writeLog(llError,"initHardware","Set eth1 mac address failed");
		return false;
	}

	strCmd=QString("ifconfig eth1 %1 netmask %2").arg(gEthernetParm[1].ip)
			.arg(gEthernetParm[1].netmask);
	if(::system(strCmd.toAscii().data())==-1)
	{
		glog->writeLog(llError,"initHardWare","Set eth1 ip address failed");
		return false;
	}

	strCmd=QString("ifconfig can0 down");
	::system(strCmd.toAscii().data());

	strCmd=QString("ip link set can0 type can bitrate %1").arg(getCanBitrate(gCan0Bitrate));
	if(::system(strCmd.toAscii().data())==-1)
	{
		glog->writeLog(llError,"initHardware","Set can0 bitrate failed");
		return false;
	}

	strCmd=QString("ifconfig can1 down");
	::system(strCmd.toAscii().data());

	strCmd=QString("ip link set can1 type can bitrate %1").arg(getCanBitrate(gCan1Bitrate));
	if(::system(strCmd.toAscii().data())==-1)
	{
		glog->writeLog(llError,"initHardware","Set can1 bitrate failed");
		return false;
	}

	// We put battery parameter here because we think it as a hardware
	QTextCodec* codec=QTextCodec::codecForName("utf-8");
	gbattery.desc=codec->toUnicode("弘毅电气");
	gbattery.lstChnnlDesc
		<<codec->toUnicode("模块1端电压")
		<<codec->toUnicode("模块2端电压")
		<<codec->toUnicode("模块3端电压")
		<<codec->toUnicode("模块4端电压")
		<<codec->toUnicode("模块5端电压")
		<<codec->toUnicode("模块6端电压")
		<<codec->toUnicode("模块7端电压")
		<<codec->toUnicode("模块8端电压")
		<<codec->toUnicode("模块9端电压")
		<<codec->toUnicode("模块10端电压")
		<<codec->toUnicode("模块11端电压")
		<<codec->toUnicode("模块12端电压")
		<<codec->toUnicode("电流1")
		<<codec->toUnicode("电流2")
		<<codec->toUnicode("温度1")
		<<codec->toUnicode("温度2");

	ValuePrecision precisionVoltage,precisionCurrent,precisionTemp;
	ValueRange rangeVoltage,rangeCurrent,rangeTemp;

	precisionVoltage.intDigits=2;
	precisionVoltage.decimalDigits=3;

	precisionCurrent.intDigits=2;
	precisionCurrent.decimalDigits=3;

	precisionTemp.intDigits=2;
	precisionTemp.decimalDigits=1;

	gbattery.lstChnnlPrecision
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionVoltage
		<<precisionCurrent
		<<precisionCurrent
		<<precisionTemp
		<<precisionTemp;

	rangeVoltage.minValue=1000;
	rangeVoltage.maxValue=20000;
	rangeVoltage.valueStep=1;

	rangeCurrent.minValue=0;
	rangeCurrent.maxValue=20000;
	rangeCurrent.valueStep=1;

	rangeTemp.minValue=0;
	rangeTemp.maxValue=1000;
	rangeTemp.valueStep=1;

	gbattery.lstChnnlRange
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeVoltage
		<<rangeCurrent
		<<rangeCurrent
		<<rangeTemp
		<<rangeTemp;

	gbattery.lstChnnlDimension
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"V"
		<<"A"
		<<"A"
		<<"C"
		<<"C";

	for(int i=0;i<gbattery.lstChnnlDesc.size();i++)
		gbattery.lstChnnlCof<<1000;

	gbattery.lstMesureChnnlDesc
		<<codec->toUnicode("总电压")
		<<codec->toUnicode("电流")
		<<codec->toUnicode("温度")
		<<codec->toUnicode("容量")
		<<codec->toUnicode("模块1端电压")
		<<codec->toUnicode("模块2端电压")
		<<codec->toUnicode("模块3端电压")
		<<codec->toUnicode("模块4端电压")
		<<codec->toUnicode("模块5端电压")
		<<codec->toUnicode("模块6端电压")
		<<codec->toUnicode("模块7端电压")
		<<codec->toUnicode("模块8端电压")
		<<codec->toUnicode("模块9端电压")
		<<codec->toUnicode("模块10端电压")
		<<codec->toUnicode("模块11端电压")
		<<codec->toUnicode("模块12端电压");

	gbattery.lstAlarmDesc
		<<codec->toUnicode("模块1端电压过高")
		<<codec->toUnicode("模块2端电压过高")
		<<codec->toUnicode("模块3端电压过高")
		<<codec->toUnicode("模块4端电压过高")
		<<codec->toUnicode("模块5端电压过高")
		<<codec->toUnicode("模块6端电压过高")
		<<codec->toUnicode("模块7端电压过高")
		<<codec->toUnicode("模块8端电压过高")
		<<codec->toUnicode("模块9端电压过高")
		<<codec->toUnicode("模块10端电压过高")
		<<codec->toUnicode("模块11端电压过高")
		<<codec->toUnicode("模块12端电压过高")
		<<codec->toUnicode("总电压过高")
		<<codec->toUnicode("模块1端电压过低")
		<<codec->toUnicode("模块2端电压过低")
		<<codec->toUnicode("模块3端电压过低")
		<<codec->toUnicode("模块4端电压过低")
		<<codec->toUnicode("模块5端电压过低")
		<<codec->toUnicode("模块6端电压过低")
		<<codec->toUnicode("模块7端电压过低")
		<<codec->toUnicode("模块8端电压过低")
		<<codec->toUnicode("模块9端电压过低")
		<<codec->toUnicode("模块10端电压过低")
		<<codec->toUnicode("模块11端电压过低")
		<<codec->toUnicode("模块12端电压过低")
		<<codec->toUnicode("总电压过低")
		<<codec->toUnicode("充电电流过大")
		<<codec->toUnicode("放电电流过大")
		<<codec->toUnicode("温度过高")
		<<codec->toUnicode("模块上电");

	for(int i=0;i<gbattery.lstMesureChnnlDesc.size();i++)
		gbattery.lstMesureValue.append(0);

	for(int i=0;i<gbattery.lstAlarmDesc.size();i++)
		gbattery.lstDiValue.append(0);

	return true;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTextCodec::setCodecForTr(QTextCodec::codecForName("System"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));

    qWarning()<<"Starting MPR310 application VERSION "<<gversion;

    bool useDefault=false;
    bool nfs=false;

    gWorkDir.clear();
    gActiveSector.clear();

    QString arg;
    for(int i=0;i<argc;i++)
    {
    	arg.clear();
    	arg.append(argv[i]);
    	arg.remove(QChar('-'));
    	if(arg=="default")
    	{
    		useDefault=true;
    		gWorkDir=QDir::currentPath()+"/config";
    		gActiveSector="default";
    	}
    	else if(arg=="nfs")
    	{
    		nfs=true;
    	}
    	else if(arg.contains("config"))
    	{
    		int subIndex=arg.indexOf(QChar('='));
    		gWorkDir=arg.mid(subIndex+1);
    	}
    	else if(arg.contains("active-sector"))
    	{
    		int subIndex=arg.indexOf(QChar('='));
    		gActiveSector=arg.mid(subIndex+1);
    	}
    }

    if((!gWorkDir.size())&&(!gActiveSector.size()))
    {
    	gWorkDir=QDir::currentPath()+"/config";
		gActiveSector="default";
    	useDefault=true;
    }
    else if(gWorkDir.size()&&(!gActiveSector.size()))
    {
    	QSettings sectorSetting(gWorkDir+"/sector.ini",QSettings::IniFormat);
    	sectorSetting.beginGroup("Sector");
    	if(!sectorSetting.contains("Active"))
    	{
    		sectorSetting.setValue("Active","default");
    		useDefault=true;
    	}
    	gActiveSector=sectorSetting.value("Active").toString();
    	sectorSetting.endGroup();
    }
    else if(gActiveSector=="default")
    {
    	useDefault=true;
    }

    if(useDefault)
    {
    	ParamUseDefault();
    	saveParam();
    }
    else
    {
    	loadParam();
    }

    qWarning()<<"Initializing hardware";
    if(!initHardware(nfs))
    {
    	qWarning()<<"Initialize hardware failed,exit now";
    	return 1;
    }

    qWarning()<<"Initializing watch dog module";
    gwatchDog=new kWatchDog;
    gwatchDog->start();

    QObject::connect(gwatchDog,SIGNAL(finished()),&a,SLOT(quit()));

    qWarning()<<"Initializing log module";
    glog=new klog(gWorkDir+"/log",llError);

    qWarning()<<"Initializing device module";
    KjDeviceList *lstDevice=new KjDeviceList();
    if(!lstDevice->init())
    {
    	qWarning()<<"Initialize device module failed,exit now";
    	return 1;
    }

    qWarning()<<"Initializing Panel led module";
	gled=new PanelLed;
	if(!gled->start(5000))
	{
		qWarning()<<"Initialize Panel led module failed,exit now";
		return 1;
	}

	qWarning()<<"Initializing device protocol module";
	DeviceProtocolManager* devProtocolManager=new DeviceProtocolManager(lstDevice);
	if(!devProtocolManager->startProtocol())
	{
		qWarning()<<"Initialize device protocol module failed,exit now";
		return 1;
	}

    qWarning()<<"Initializing Protocol 103 module";
    MprDatagramProcessor* mprDgProcessor=new MprDatagramProcessor(lstDevice);
    if(!mprDgProcessor->start(5000))
    {
    	qWarning()<<"Initialize datagram processor failed";
    	return 1;
    }

    Hy103ClientManager* hy103Eth0=new Hy103ClientManager("eth0",lstDevice,mprDgProcessor);
    if(!hy103Eth0->start(5000))
    {
    	qWarning()<<"Initialize Protocol 103 module for eth0 failed,exit now";
		return 1;
    }

    Hy103ClientManager* hy103Eth1=new Hy103ClientManager("eth1",lstDevice,mprDgProcessor);
	if(!hy103Eth1->start(5000))
	{
		qWarning()<<"Initialize Protocol 103 module for eth1 failed,exit now";
		return 1;
	}

	qWarning()<<"Initializing Ethernet battery protocol";
	EPBListener* epbListener=new EPBListener("eth0",lstDevice);
	if(!epbListener->start(1000000))
	{
		qWarning()<<"Initialize Ethernet battery protocol for eth0 failed,exit now";
		return 1;
	}

	qWarning()<<"Initializing debug module";
	Debug* debug=new Debug();
	if(!debug->start(5000))
	{
		qWarning()<<"Initialize debug module failed,exit now";
		return 1;
	}

	qWarning()<<"Initialize success,entering event loop";

    return a.exec();
}
